function Penguin (battle) {
	// Misc
	var PENGUIN_SIZE_W = 80;
	var PENGUIN_SIZE_H = 80;
	var PENGUIN_MOVE_FRAME_LENGTH = 150;
	var PENGUIN_FLOAT_FRAME_LENGTH = 350;
	var PENGUIN_JUMPING_DURATION = 450;
	var PENGUIN_JUMP_FORCE = 170 * 0.001;
	var PENGUIN_AUTO_CORRECT_OFFSET = 20;
	var PENGUIN_THROWING_DURATION = 300;
	
	var PENGUIN_OFFSET_X = (MAP_TILE_SIZE - PENGUIN_SIZE_W) * 0.5;
	var PENGUIN_OFFSET_Y = (MAP_TILE_SIZE - PENGUIN_SIZE_H) * 0.5;
	
	// Penguin State
	var PENGUIN_STATE_STANDING = 0;
	var PENGUIN_STATE_MOVING = 1;
	var PENGUIN_STATE_THROWING = 2;
	var PENGUIN_STATE_JUMPING = 3;
	var PENGUIN_STATE_FLOATING = 4;
	var PENGUIN_STATE_SWIMMING = 5;
	
	// Direction enum
	var DIRECTION_DOWN = 0;
	var DIRECTION_LEFT = 1;
	var DIRECTION_UP = 2;
	var DIRECTION_RIGHT = 3;
	
	// Animation count
	var PENGUIN_ANIMATION_COUNT_STANDING = 1;
	var PENGUIN_ANIMATION_COUNT_MOVING = 3;
	var PENGUIN_ANIMATION_COUNT_THROWING = 2;
	var PENGUIN_ANIMATION_COUNT_JUMPING = 2;
	var PENGUIN_ANIMATION_COUNT_FLOATING = 2;
	var PENGUIN_ANIMATION_COUNT_SWIMMING = 3;
	
	
	// Order enum
	var ORDER_ACTION_STOP = 0;
	var ORDER_ACTION_MOVE = 1;
	var ORDER_ACTION_CHARGE = 2;
	var ORDER_ACTION_THROW = 3;
	//var ORDER_ACTION_SKILL_1 = 0;
	
	// Penguin property
	this.m_x = 0;
	this.m_y = 0;
	this.m_h = 0;
	this.m_orderMove = 0;
	this.m_orderAction = 0;
	this.m_orderDirection = 0;
	this.m_orderThrowForce = 0;
	
	this.m_moveSpeed = MAP_TILE_SIZE * 2 * 0.001;
	this.m_swimSpeed = MAP_TILE_SIZE * 6 * 0.001;
	this.m_isMoving = false;
	this.m_jumpDown = false;
	this.m_state = PENGUIN_STATE_STANDING;
	this.m_direction = DIRECTION_DOWN;
	
	this.m_HP = 0;
	this.m_maxHP = 0;
	this.m_status = 0;
	this.m_energy = 0;
	this.m_maxEnergy = 0;

	this.m_mainBombDamage = 0;	
	this.m_mainBombRadius = 0;	
	
		
	var animationCount = 0;
	this.m_animationStep = 0;
	
	
	// Image
	var penguinImage = g_graphicEngine.LoadImage("Data/ActionPhase/Penguin/Penguin.png");

	// Init source position in the image
	var actionSource = new Array();
	for (var i=PENGUIN_STATE_STANDING; i<=PENGUIN_STATE_SWIMMING; i++) {
		actionSource[i] = new Array();
		for (var j=DIRECTION_DOWN; j<=DIRECTION_RIGHT; j++) {
			actionSource[i][j] = new Array();
		}
	}
	
	// Hard-code the source info for all animation
	for (var i=DIRECTION_DOWN; i<=DIRECTION_RIGHT; i++) {
		actionSource[PENGUIN_STATE_STANDING][i][0]  = new SourceRect (penguinImage, PENGUIN_SIZE_W * 1, PENGUIN_SIZE_H * i, PENGUIN_SIZE_W, PENGUIN_SIZE_H);
	}
	for (var i=DIRECTION_DOWN; i<=DIRECTION_RIGHT; i++) {
		for (var j=0; j<=PENGUIN_ANIMATION_COUNT_MOVING; j++) {
			actionSource[PENGUIN_STATE_MOVING][i][j]  = new SourceRect (penguinImage, PENGUIN_SIZE_W * j, PENGUIN_SIZE_H * i, PENGUIN_SIZE_W, PENGUIN_SIZE_H);
		}
	}
	for (var i=DIRECTION_DOWN; i<=DIRECTION_RIGHT; i++) {
		for (var j=0; j<=PENGUIN_ANIMATION_COUNT_JUMPING; j++) {
			actionSource[PENGUIN_STATE_JUMPING][i][j]  = new SourceRect (penguinImage, PENGUIN_SIZE_W * j + PENGUIN_SIZE_W * 5, PENGUIN_SIZE_H * i, PENGUIN_SIZE_W, PENGUIN_SIZE_H);
		}
	}
	
	for (var i=DIRECTION_DOWN; i<=DIRECTION_RIGHT; i++) {
		for (var j=0; j<=PENGUIN_ANIMATION_COUNT_FLOATING; j++) {
			actionSource[PENGUIN_STATE_FLOATING][i][j]  = new SourceRect (penguinImage, PENGUIN_SIZE_W * j + PENGUIN_SIZE_W * 5, PENGUIN_SIZE_H * i + PENGUIN_SIZE_H * 4, PENGUIN_SIZE_W, PENGUIN_SIZE_H);
		}
	}
	
	for (var i=DIRECTION_DOWN; i<=DIRECTION_RIGHT; i++) {
		for (var j=0; j<=PENGUIN_ANIMATION_COUNT_SWIMMING; j++) {
			actionSource[PENGUIN_STATE_SWIMMING][i][j]  = new SourceRect (penguinImage, PENGUIN_SIZE_W * j, PENGUIN_SIZE_H * i + PENGUIN_SIZE_H * 4, PENGUIN_SIZE_W, PENGUIN_SIZE_H);
		}
	}
	
	for (var i=DIRECTION_DOWN; i<=DIRECTION_RIGHT; i++) {
		for (var j=0; j<=PENGUIN_ANIMATION_COUNT_THROWING; j++) {
			actionSource[PENGUIN_STATE_THROWING][i][j]  = new SourceRect (penguinImage, PENGUIN_SIZE_W * j+ PENGUIN_SIZE_W * 9, PENGUIN_SIZE_H * i, PENGUIN_SIZE_W, PENGUIN_SIZE_H);
		}
	}
	
	
	
	
	
	var HP_BAR_W = 60;
	var HP_BAR_H = 5;
	var HP_BAR_OFFSET_X = 0;
	var HP_BAR_OFFSET_Y = 0;
	var hpBar = g_graphicEngine.LoadImage("Data/ActionPhase/UI/SmallHPBar.png");
	
	
	
	
	
	
	this.Init = function () {
	
	}
	
	
	
	
	
	
	
	
	this.Draw = function () {
		var penguinAlpha = 1;
		
		if (this.m_state == PENGUIN_STATE_SWIMMING) {
			penguinAlpha = 0.5;
		}
		
		g_graphicEngine.Draw (g_context, actionSource[this.m_state][this.m_direction][this.m_animationStep].m_id, actionSource[this.m_state][this.m_direction][this.m_animationStep].m_x, actionSource[this.m_state][this.m_direction][this.m_animationStep].m_y,
						actionSource[this.m_state][this.m_direction][this.m_animationStep].m_w, actionSource[this.m_state][this.m_direction][this.m_animationStep].m_h, this.m_x + PENGUIN_OFFSET_X + BATTLE_OFFSET_X, this.m_y + PENGUIN_OFFSET_Y - this.m_h + BATTLE_OFFSET_Y, PENGUIN_SIZE_W, PENGUIN_SIZE_H, penguinAlpha);
		
		// Draw the HP Bar
		g_graphicEngine.Draw (g_context, hpBar, 0, 0, HP_BAR_W, HP_BAR_H, this.m_x + HP_BAR_OFFSET_X + BATTLE_OFFSET_X, this.m_y + PENGUIN_OFFSET_Y + HP_BAR_OFFSET_Y - this.m_h , HP_BAR_W, HP_BAR_H);
		g_graphicEngine.Draw (g_context, hpBar, 0, HP_BAR_H, (HP_BAR_W * (this.m_HP / this.m_maxHP)) >> 0, HP_BAR_H, this.m_x + HP_BAR_OFFSET_X + BATTLE_OFFSET_X, this.m_y + PENGUIN_OFFSET_Y + HP_BAR_OFFSET_Y - this.m_h, (HP_BAR_W * (this.m_HP / this.m_maxHP)) >> 0, HP_BAR_H);
		
	}
	
	
	
	
	
	
	this.Update = function () {
		if (this.m_orderMove == ORDER_ACTION_STOP) {
			if (this.m_state == PENGUIN_STATE_MOVING || this.m_state == PENGUIN_STATE_SWIMMING) {
				this.Stop();
			}
		}
		else if (this.m_orderMove == ORDER_ACTION_MOVE) {
			if (this.m_state == PENGUIN_STATE_STANDING || this.m_state == PENGUIN_STATE_MOVING || this.m_state == PENGUIN_STATE_FLOATING || this.m_state == PENGUIN_STATE_SWIMMING) {
				this.Move(this.m_orderDirection);
			}
		}
		
		if (this.m_orderAction == ORDER_ACTION_CHARGE) {
			if (this.m_state == PENGUIN_STATE_STANDING || this.m_state == PENGUIN_STATE_MOVING) {
				this.m_state = PENGUIN_STATE_THROWING;
				this.m_animationStep = 0;
				animationCount = 0;
				this.m_orderAction = 0;
			}
		}
		else if (this.m_orderAction == ORDER_ACTION_THROW) {
			if (this.m_state == PENGUIN_STATE_THROWING && this.m_animationStep == 0) {
				this.m_animationStep = 1;
				animationCount = 0;
				this.m_orderAction = 0;
				
				battle.ThrowBomb (this.m_x + MAP_TILE_SIZE * 0.5, this.m_y + MAP_TILE_SIZE * 0.5, this.m_direction, this.m_orderThrowForce, this.m_mainBombDamage, this.m_mainBombRadius);
			}
		}
		
		if (this.m_state == PENGUIN_STATE_THROWING) {
			this.m_direction = this.m_orderDirection;
			if (this.m_animationStep == 1) {
				animationCount += g_deltaTime;
				if (animationCount >= PENGUIN_THROWING_DURATION) {
					this.m_state = PENGUIN_STATE_STANDING;
					this.m_animationStep = 0;
					animationCount = 0;
				}
			}
		}
	
	
	
	
		if (this.m_state == PENGUIN_STATE_STANDING) {
			if (this.m_isMoving == true) {
				this.m_state = PENGUIN_STATE_MOVING;
				this.m_animationStep = 0;
				animationCount = 0;
			}
		}
		
		if (this.m_state == PENGUIN_STATE_MOVING) {
			if (this.m_isMoving == false) {
				this.m_state = PENGUIN_STATE_STANDING;
				this.m_animationStep = 0;
				animationCount = 0;
			}
			
			
			if (this.m_direction == DIRECTION_DOWN) {
				this.m_y += this.m_moveSpeed * g_deltaTime;
				if (this.m_y >= MAP_TILE_SIZE * (MAP_SIZE_H-1)) {
					this.m_y = MAP_TILE_SIZE * (MAP_SIZE_H-1);
					this.Stop();
				}
			}
			else if (this.m_direction == DIRECTION_LEFT) {
				this.m_x -= this.m_moveSpeed * g_deltaTime;
				if (this.m_x <= 0) {
					this.m_x = 0;
					this.Stop();
				}
			}
			else if (this.m_direction == DIRECTION_UP) {
				this.m_y -= this.m_moveSpeed * g_deltaTime;
				if (this.m_y <= 0) {
					this.m_y = 0;
					this.Stop();
				}
			}
			else if (this.m_direction == DIRECTION_RIGHT) {
				this.m_x += this.m_moveSpeed * g_deltaTime;
				if (this.m_x >= MAP_TILE_SIZE * (MAP_SIZE_W-1)) {
					this.m_x = MAP_TILE_SIZE * (MAP_SIZE_W-1);
					this.Stop();
				}
			}
			
			if (this.m_state == PENGUIN_STATE_MOVING) {
				animationCount += g_deltaTime;
				if (animationCount >= PENGUIN_MOVE_FRAME_LENGTH) {
					animationCount -= PENGUIN_MOVE_FRAME_LENGTH;
					if (animationCount > PENGUIN_MOVE_FRAME_LENGTH) {
						animationCount = 0;
					}
					
					this.m_animationStep ++;
					if (this.m_animationStep >= PENGUIN_ANIMATION_COUNT_MOVING) {
						this.m_animationStep = 0;
					}
				}
			}
		}
		
		
		if (this.m_state == PENGUIN_STATE_JUMPING) {
			if (this.m_direction == DIRECTION_DOWN) {
				this.m_y += this.m_moveSpeed * g_deltaTime;
			}
			else if (this.m_direction == DIRECTION_LEFT) {
				this.m_x -= this.m_moveSpeed * g_deltaTime;
			}
			else if (this.m_direction == DIRECTION_UP) {
				this.m_y -= this.m_moveSpeed * g_deltaTime;
			}
			else if (this.m_direction == DIRECTION_RIGHT) {
				this.m_x += this.m_moveSpeed * g_deltaTime;
			}
			
			if (this.m_state == PENGUIN_STATE_JUMPING) {
				if (this.m_animationStep == 0) {
					this.m_h += PENGUIN_JUMP_FORCE * g_deltaTime;
				}
				else if (this.m_animationStep == 1) {
					this.m_h -= PENGUIN_JUMP_FORCE * g_deltaTime;
				}
				
				animationCount += g_deltaTime;
				
				if (animationCount >= PENGUIN_JUMPING_DURATION) {
					this.m_animationStep = 0;
					if (this.m_jumpDown == true) 
						this.m_state = PENGUIN_STATE_FLOATING;
					else
						this.m_state = PENGUIN_STATE_STANDING;
					animationCount = 0;
					
					this.m_h = 0;
					
					/*
					if (this.m_direction == DIRECTION_DOWN) {
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else if (this.m_direction == DIRECTION_LEFT) {
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else if (this.m_direction == DIRECTION_UP) {
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else if (this.m_direction == DIRECTION_RIGHT) {
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					*/
				}
				else if (animationCount >= PENGUIN_JUMPING_DURATION * 0.95) {
					if (this.m_jumpDown == true) 
						battle.StartExplosion (0, this.m_x + MAP_TILE_SIZE * 0.5, this.m_y);
				}
				else if (animationCount >= PENGUIN_JUMPING_DURATION * 0.5) {
					this.m_animationStep = 1;
				}
			}
		}
		
		
		if (this.m_state == PENGUIN_STATE_FLOATING) {
			animationCount += g_deltaTime;
			
			if (animationCount >= PENGUIN_FLOAT_FRAME_LENGTH) {
				animationCount -= PENGUIN_FLOAT_FRAME_LENGTH;
				if (animationCount > PENGUIN_FLOAT_FRAME_LENGTH) {
					animationCount = 0;
				}
				
				this.m_animationStep ++;
				if (this.m_animationStep >= PENGUIN_ANIMATION_COUNT_FLOATING) {
					this.m_animationStep = 0;
				}
			}
			
			if (this.m_isMoving == true) {
				this.m_state = PENGUIN_STATE_SWIMMING;
				this.m_animationStep = 0;
				animationCount = 0;
			}
		}
		
		if (this.m_state == PENGUIN_STATE_SWIMMING) {
			if (this.m_isMoving == false) {
				this.m_state = PENGUIN_STATE_FLOATING;
				this.m_animationStep = 0;
				animationCount = 0;
			}
			
			if (this.m_direction == DIRECTION_DOWN) {
				this.m_y += this.m_swimSpeed * g_deltaTime;
				if (this.m_y >= MAP_TILE_SIZE * (MAP_SIZE_H-1)) {
					this.m_y = MAP_TILE_SIZE * (MAP_SIZE_H-1);
					this.Stop();
				}
			}
			else if (this.m_direction == DIRECTION_LEFT) {
				this.m_x -= this.m_swimSpeed * g_deltaTime;
				if (this.m_x <= 0) {
					this.m_x = 0;
					this.Stop();
				}
			}
			else if (this.m_direction == DIRECTION_UP) {
				this.m_y -= this.m_swimSpeed * g_deltaTime;
				if (this.m_y <= 0) {
					this.m_y = 0;
					this.Stop();
				}
			}
			else if (this.m_direction == DIRECTION_RIGHT) {
				this.m_x += this.m_swimSpeed * g_deltaTime;
				if (this.m_x >= MAP_TILE_SIZE * (MAP_SIZE_W-1)) {
					this.m_x = MAP_TILE_SIZE * (MAP_SIZE_W-1);
					this.Stop();
				}
			}
			
			if (this.m_state == PENGUIN_STATE_SWIMMING) {
				animationCount += g_deltaTime;
				if (animationCount >= PENGUIN_MOVE_FRAME_LENGTH) {
					animationCount -= PENGUIN_MOVE_FRAME_LENGTH;
					if (animationCount > PENGUIN_MOVE_FRAME_LENGTH) {
						animationCount = 0;
					}
					
					this.m_animationStep ++;
					if (this.m_animationStep >= PENGUIN_ANIMATION_COUNT_SWIMMING) {
						this.m_animationStep = 0;
					}
				}
			}
		}
		
		this.CheckCollision();
	}
	
	
	this.CheckCollision = function () {
		var pathMap = battle.pathMap;
		
		var cx = (this.m_x / MAP_TILE_SIZE) >> 0;
		var cy = (this.m_y / MAP_TILE_SIZE) >> 0;
		var shiftCell = 0;
		
		if (this.m_state == PENGUIN_STATE_MOVING) {
			if (this.m_direction == DIRECTION_DOWN) {
				if (this.m_x % MAP_TILE_SIZE < PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = -1;
				}
				else if (this.m_x % MAP_TILE_SIZE > MAP_TILE_SIZE - PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = 1;
				}
				
				if (pathMap [cx][cy+1] >= GROUND_ENTITY && pathMap [cx+1][cy+1] >= GROUND_ENTITY) {
					this.m_y = cy * MAP_TILE_SIZE;
					this.Stop(); 
				}
				else if (pathMap [cx][cy+1] < GROUND_ENTITY && pathMap [cx+1][cy+1] >= GROUND_ENTITY) {
					if (shiftCell == -1) {
						if (pathMap [cx][cy+1] == GROUND_WATER) {
							this.m_y = cy * MAP_TILE_SIZE;
							this.Jump(true);
						}
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else {
						this.m_y = cy * MAP_TILE_SIZE;
						this.Stop(); 
					}
				}
				else if (pathMap [cx][cy+1] >= GROUND_ENTITY && pathMap [cx+1][cy+1] < GROUND_ENTITY) {
					if (shiftCell == 1) {
						if (pathMap [cx+1][cy+1] == GROUND_WATER) {
							this.m_y = cy * MAP_TILE_SIZE;
							this.Jump(true);
						}
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
					}
					else {
						this.m_y = cy * MAP_TILE_SIZE;
						this.Stop();
					}
				}
				else if (pathMap [cx][cy+1] < GROUND_ENTITY && pathMap [cx+1][cy+1] < GROUND_ENTITY) {
					if (pathMap [cx][cy+1] == GROUND_WATER && pathMap [cx+1][cy+1] == GROUND_EMPTY) {
						if (shiftCell == -1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
							this.m_y = cy * MAP_TILE_SIZE;
							this.Jump(true);
						}
						else if (shiftCell == 1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
						}
						else {
							this.m_y = cy * MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy+1] == GROUND_EMPTY && pathMap [cx+1][cy+1] == GROUND_WATER) {
						if (shiftCell == 1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.m_y = cy * MAP_TILE_SIZE;
							this.Jump(true);
						}
						else if (shiftCell == -1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
						}
						else {
							this.m_y = cy * MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy+1] == GROUND_WATER && pathMap [cx+1][cy+1] == GROUND_WATER) {
						this.m_y = cy * MAP_TILE_SIZE;
						this.Jump(true);
					}
				}
			}
			else if (this.m_direction == DIRECTION_LEFT) {
				if (this.m_y % MAP_TILE_SIZE < PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = -1;
				}
				else if (this.m_y % MAP_TILE_SIZE > MAP_TILE_SIZE - PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = 1;
				}
				
				if (pathMap [cx][cy] >= GROUND_ENTITY && pathMap [cx][cy+1] >= GROUND_ENTITY) {
					this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
					this.Stop(); 
				}
				else if (pathMap [cx][cy] < GROUND_ENTITY && pathMap [cx][cy+1] >= GROUND_ENTITY) {
					if (shiftCell == -1) {
						if (pathMap [cx][cy] == GROUND_WATER) {
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(true);
						}
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else {
						this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Stop(); 
					}
				}
				else if (pathMap [cx][cy] >= GROUND_ENTITY && pathMap [cx][cy+1] < GROUND_ENTITY) {
					if (shiftCell == 1) {
						if (pathMap [cx][cy+1] == GROUND_WATER) {
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(true);
						}
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
					}
					else {
						this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Stop();
					}
				}
				else if (pathMap [cx][cy] < GROUND_ENTITY && pathMap [cx][cy+1] < GROUND_ENTITY) {
					if (pathMap [cx][cy] == GROUND_WATER && pathMap [cx][cy+1] == GROUND_EMPTY) {
						if (shiftCell == -1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(true);
						}
						else if (shiftCell == 1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
						}
						else {
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy] == GROUND_EMPTY && pathMap [cx][cy+1] == GROUND_WATER) {
						if (shiftCell == 1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(true);
						}
						else if (shiftCell == -1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
						}
						else {
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy] == GROUND_WATER && pathMap [cx][cy+1] == GROUND_WATER) {
						this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Jump(true);
					}
				}
			}
			else if (this.m_direction == DIRECTION_UP) {
				if (this.m_x % MAP_TILE_SIZE < PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = -1;
				}
				else if (this.m_x % MAP_TILE_SIZE > MAP_TILE_SIZE - PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = 1;
				}
				if (pathMap [cx][cy] >= GROUND_ENTITY && pathMap [cx+1][cy] >= GROUND_ENTITY) {
					this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
					this.Stop(); 
				}
				else if (pathMap [cx][cy] < GROUND_ENTITY && pathMap [cx+1][cy] >= GROUND_ENTITY) {
					if (shiftCell == -1) {
						if (pathMap [cx][cy] == GROUND_WATER) {
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(true);
						}
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else {
						this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Stop(); 
					}
				}
				else if (pathMap [cx][cy] >= GROUND_ENTITY && pathMap [cx+1][cy] < GROUND_ENTITY) {
					if (shiftCell == 1) {
						if (pathMap [cx+1][cy] == GROUND_WATER) {
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(true);
						}
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
					}
					else {
						this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Stop();
					}
				}
				else if (pathMap [cx][cy] < GROUND_ENTITY && pathMap [cx+1][cy] < GROUND_ENTITY) {
					if (pathMap [cx][cy] == GROUND_WATER && pathMap [cx+1][cy] == GROUND_EMPTY) {
						if (shiftCell == -1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(true);
						}
						else if (shiftCell == 1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
						}
						else {
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy] == GROUND_EMPTY && pathMap [cx+1][cy] == GROUND_WATER) {
						if (shiftCell == 1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(true);
						}
						else if (shiftCell == -1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
						}
						else {
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy] == GROUND_WATER && pathMap [cx+1][cy] == GROUND_WATER) {
						this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Jump(true);
					}
				}
			}
			else if (this.m_direction == DIRECTION_RIGHT) {
				if (this.m_y % MAP_TILE_SIZE < PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = -1;
				}
				else if (this.m_y % MAP_TILE_SIZE > MAP_TILE_SIZE - PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = 1;
				}
				
				if (pathMap [cx+1][cy] >= GROUND_ENTITY && pathMap [cx+1][cy+1] >= GROUND_ENTITY) {
					this.m_x = cx * MAP_TILE_SIZE;
					this.Stop(); 
				}
				else if (pathMap [cx+1][cy] < GROUND_ENTITY && pathMap [cx+1][cy+1] >= GROUND_ENTITY) {
					if (shiftCell == -1) {
						if (pathMap [cx+1][cy] == GROUND_WATER) {
							this.m_x = cx * MAP_TILE_SIZE;
							this.Jump(true);
						}
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else {
						this.m_x = cx * MAP_TILE_SIZE;
						this.Stop(); 
					}
				}
				else if (pathMap [cx+1][cy] >= GROUND_ENTITY && pathMap [cx+1][cy+1] < GROUND_ENTITY) {
					if (shiftCell == 1) {
						if (pathMap [cx+1][cy+1] == GROUND_WATER) {
							this.m_x = cx * MAP_TILE_SIZE;
							this.Jump(true);
						}
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
					}
					else {
						this.m_x = cx * MAP_TILE_SIZE;
						this.Stop();
					}
				}
				else if (pathMap [cx+1][cy] < GROUND_ENTITY && pathMap [cx+1][cy+1] < GROUND_ENTITY) {
					if (pathMap [cx+1][cy] == GROUND_WATER && pathMap [cx+1][cy+1] == GROUND_EMPTY) {
						if (shiftCell == -1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
							this.m_x = cx * MAP_TILE_SIZE;
							this.Jump(true);
						}
						else if (shiftCell == 1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
						}
						else {
							this.m_x = cx * MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx+1][cy] == GROUND_EMPTY && pathMap [cx+1][cy+1] == GROUND_WATER) {
						if (shiftCell == 1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.m_x = cx * MAP_TILE_SIZE;
							this.Jump(true);
						}
						else if (shiftCell == -1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
						}
						else {
							this.m_x = cx * MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx+1][cy] == GROUND_WATER && pathMap [cx+1][cy+1] == GROUND_WATER) {
						this.m_x = cx * MAP_TILE_SIZE;
						this.Jump(true);
					}
				}
			}
		}
		else if (this.m_state == PENGUIN_STATE_SWIMMING) {
			if (this.m_direction == DIRECTION_DOWN) {
				if (this.m_x % MAP_TILE_SIZE < PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = -1;
				}
				else if (this.m_x % MAP_TILE_SIZE > MAP_TILE_SIZE - PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = 1;
				}
				
				if (pathMap [cx][cy+1] >= GROUND_ENTITY && pathMap [cx+1][cy+1] >= GROUND_ENTITY) {
					this.m_y = cy * MAP_TILE_SIZE;
					this.Stop(); 
				}
				else if (pathMap [cx][cy+1] < GROUND_ENTITY && pathMap [cx+1][cy+1] >= GROUND_ENTITY) {
					if (shiftCell == -1) {
						if (pathMap [cx][cy+1] == GROUND_EMPTY) {
							this.m_y = cy * MAP_TILE_SIZE;
							this.Jump(false);
						}
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else {
						this.m_y = cy * MAP_TILE_SIZE;
						this.Stop(); 
					}
				}
				else if (pathMap [cx][cy+1] >= GROUND_ENTITY && pathMap [cx+1][cy+1] < GROUND_ENTITY) {
					if (shiftCell == 1) {
						if (pathMap [cx+1][cy+1] == GROUND_EMPTY) {
							this.m_y = cy * MAP_TILE_SIZE;
							this.Jump(false);
						}
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
					}
					else {
						this.m_y = cy * MAP_TILE_SIZE;
						this.Stop();
					}
				}
				else if (pathMap [cx][cy+1] < GROUND_ENTITY && pathMap [cx+1][cy+1] < GROUND_ENTITY) {
					if (pathMap [cx][cy+1] == GROUND_EMPTY && pathMap [cx+1][cy+1] == GROUND_WATER) {
						if (shiftCell == -1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
							this.m_y = cy * MAP_TILE_SIZE;
							this.Jump(false);
						}
						else if (shiftCell == 1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
						}
						else {
							this.m_y = cy * MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy+1] == GROUND_WATER && pathMap [cx+1][cy+1] == GROUND_EMPTY) {
						if (shiftCell == 1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.m_y = cy * MAP_TILE_SIZE;
							this.Jump(false);
						}
						else if (shiftCell == -1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
						}
						else {
							this.m_y = cy * MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy+1] == GROUND_EMPTY && pathMap [cx+1][cy+1] == GROUND_EMPTY) {
						this.m_y = cy * MAP_TILE_SIZE;
						this.Jump(false);
					}
				}
			}
			else if (this.m_direction == DIRECTION_LEFT) {
				if (this.m_y % MAP_TILE_SIZE < PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = -1;
				}
				else if (this.m_y % MAP_TILE_SIZE > MAP_TILE_SIZE - PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = 1;
				}
				
				if (pathMap [cx][cy] >= GROUND_ENTITY && pathMap [cx][cy+1] >= GROUND_ENTITY) {
					this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
					this.Stop(); 
				}
				else if (pathMap [cx][cy] < GROUND_ENTITY && pathMap [cx][cy+1] >= GROUND_ENTITY) {
					if (shiftCell == -1) {
						if (pathMap [cx][cy] == GROUND_EMPTY) {
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(false);
						}
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else {
						this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Stop(); 
					}
				}
				else if (pathMap [cx][cy] >= GROUND_ENTITY && pathMap [cx][cy+1] < GROUND_ENTITY) {
					if (shiftCell == 1) {
						if (pathMap [cx][cy+1] == GROUND_EMPTY) {
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(false);
						}
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
					}
					else {
						this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Stop();
					}
				}
				else if (pathMap [cx][cy] < GROUND_ENTITY && pathMap [cx][cy+1] < GROUND_ENTITY) {
					if (pathMap [cx][cy] == GROUND_EMPTY && pathMap [cx][cy+1] == GROUND_WATER) {
						if (shiftCell == -1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(false);
						}
						else if (shiftCell == 1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
						}
						else {
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy] == GROUND_WATER && pathMap [cx][cy+1] == GROUND_EMPTY) {
						if (shiftCell == 1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(false);
						}
						else if (shiftCell == -1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
						}
						else {
							this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy] == GROUND_EMPTY && pathMap [cx][cy+1] == GROUND_EMPTY) {
						this.m_x = cx * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Jump(false);
					}
				}
			}
			else if (this.m_direction == DIRECTION_UP) {
				if (this.m_x % MAP_TILE_SIZE < PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = -1;
				}
				else if (this.m_x % MAP_TILE_SIZE > MAP_TILE_SIZE - PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = 1;
				}
				if (pathMap [cx][cy] >= GROUND_ENTITY && pathMap [cx+1][cy] >= GROUND_ENTITY) {
					this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
					this.Stop(); 
				}
				else if (pathMap [cx][cy] < GROUND_ENTITY && pathMap [cx+1][cy] >= GROUND_ENTITY) {
					if (shiftCell == -1) {
						if (pathMap [cx][cy] == GROUND_EMPTY) {
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(false);
						}
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else {
						this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Stop(); 
					}
				}
				else if (pathMap [cx][cy] >= GROUND_ENTITY && pathMap [cx+1][cy] < GROUND_ENTITY) {
					if (shiftCell == 1) {
						if (pathMap [cx+1][cy] == GROUND_EMPTY) {
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(false);
						}
						this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
					}
					else {
						this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Stop();
					}
				}
				else if (pathMap [cx][cy] < GROUND_ENTITY && pathMap [cx+1][cy] < GROUND_ENTITY) {
					if (pathMap [cx][cy] == GROUND_EMPTY && pathMap [cx+1][cy] == GROUND_WATER) {
						if (shiftCell == -1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(false);
						}
						else if (shiftCell == 1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
						}
						else {
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy] == GROUND_WATER && pathMap [cx+1][cy] == GROUND_EMPTY) {
						if (shiftCell == 1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Jump(false);
						}
						else if (shiftCell == -1) {
							this.m_x = ((this.m_x / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
						}
						else {
							this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx][cy] == GROUND_EMPTY && pathMap [cx+1][cy] == GROUND_EMPTY) {
						this.m_y = cy * MAP_TILE_SIZE + MAP_TILE_SIZE;
						this.Jump(false);
					}
				}
			}
			else if (this.m_direction == DIRECTION_RIGHT) {
				if (this.m_y % MAP_TILE_SIZE < PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = -1;
				}
				else if (this.m_y % MAP_TILE_SIZE > MAP_TILE_SIZE - PENGUIN_AUTO_CORRECT_OFFSET) {
					shiftCell = 1;
				}
				
				if (pathMap [cx+1][cy] >= GROUND_ENTITY && pathMap [cx+1][cy+1] >= GROUND_ENTITY) {
					this.m_x = cx * MAP_TILE_SIZE;
					this.Stop(); 
				}
				else if (pathMap [cx+1][cy] < GROUND_ENTITY && pathMap [cx+1][cy+1] >= GROUND_ENTITY) {
					if (shiftCell == -1) {
						if (pathMap [cx+1][cy] == GROUND_EMPTY) {
							this.m_x = cx * MAP_TILE_SIZE;
							this.Jump(false);
						}
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
					}
					else {
						this.m_x = cx * MAP_TILE_SIZE;
						this.Stop(); 
					}
				}
				else if (pathMap [cx+1][cy] >= GROUND_ENTITY && pathMap [cx+1][cy+1] < GROUND_ENTITY) {
					if (shiftCell == 1) {
						if (pathMap [cx+1][cy+1] == GROUND_EMPTY) {
							this.m_x = cx * MAP_TILE_SIZE;
							this.Jump(false);
						}
						this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
					}
					else {
						this.m_x = cx * MAP_TILE_SIZE;
						this.Stop();
					}
				}
				else if (pathMap [cx+1][cy] < GROUND_ENTITY && pathMap [cx+1][cy+1] < GROUND_ENTITY) {
					if (pathMap [cx+1][cy] == GROUND_EMPTY && pathMap [cx+1][cy+1] == GROUND_WATER) {
						if (shiftCell == -1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
							this.m_x = cx * MAP_TILE_SIZE;
							this.Jump(false);
						}
						else if (shiftCell == 1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
						}
						else {
							this.m_x = cx * MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx+1][cy] == GROUND_WATER && pathMap [cx+1][cy+1] == GROUND_EMPTY) {
						if (shiftCell == 1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE + MAP_TILE_SIZE;
							this.m_x = cx * MAP_TILE_SIZE;
							this.Jump(false);
						}
						else if (shiftCell == -1) {
							this.m_y = ((this.m_y / MAP_TILE_SIZE) >> 0) * MAP_TILE_SIZE;
						}
						else {
							this.m_x = cx * MAP_TILE_SIZE;
							this.Stop();
						}
					}
					else if (pathMap [cx+1][cy] == GROUND_EMPTY && pathMap [cx+1][cy+1] == GROUND_EMPTY) {
						this.m_x = cx * MAP_TILE_SIZE;
						this.Jump(false);
					}
				}
			}
		}
	}
	
	this.Jump = function (jumpDown) {
		this.m_state = PENGUIN_STATE_JUMPING;
		this.m_animationStep = 0;
		animationCount = 0;
		this.m_jumpDown = jumpDown;
	}
	
	
	
	
	this.Move = function (direction) {
		if (this.m_state == PENGUIN_STATE_STANDING || this.m_state == PENGUIN_STATE_MOVING || this.m_state == PENGUIN_STATE_FLOATING || this.m_state == PENGUIN_STATE_SWIMMING) {
			this.m_direction = direction;
			this.m_isMoving = true;
		}
	}
	
	this.Stop = function () {
		this.m_isMoving = false;
		if (this.m_state == PENGUIN_STATE_STANDING || this.m_state == PENGUIN_STATE_MOVING) {
			this.m_state = PENGUIN_STATE_STANDING;
			this.m_animationStep = 0;
			animationCount = 0;
		}
		else if (this.m_state == PENGUIN_STATE_FLOATING || this.m_state == PENGUIN_STATE_SWIMMING) {
			this.m_state = PENGUIN_STATE_FLOATING;
			this.m_animationStep = 0;
			animationCount = 0;
		}
	}
	
	
	
	
	
	this.Order = function (action, direction, force) {
		// Action:
		// 0 = Stop
		// 1 = Move
		// 2 = Basic attack (charge)
		// 3 = Basic attack (release)
		// 4 -> n = Skill
		if (action == ORDER_ACTION_STOP || action == ORDER_ACTION_MOVE) {
			this.m_orderMove = action;
		}
		else {
			this.m_orderAction = action;
		}
		if (direction != null) this.m_orderDirection = direction;
		if (force != null)     this.m_orderThrowForce = force;
	}
	
	
	this.TakeDamage = function (damage) {
		this.m_HP -= damage;
		if (this.m_HP <= 0) {
			this.m_HP = 0;
			//this.m_actionStatus = HARVESTER_STATE_DYING;
			//animationCount = 0;
			//this.m_animationStep = 0;
			
			//battle.StartExplosion (3, this.m_x + MAP_TILE_SIZE * 0.5, this.m_y + MAP_TILE_SIZE * 0.5, 0, 0);
		}
	}
}